package com.ibeeking.gmc.global.g.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.enums.IndustryTypeEnum;
import com.ibeeking.gmc.global.g.rest.service.ITimeTaskService;
import com.ibeeking.found.common.entity.TimeTaskDTO;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.gmc.global.service.common.dos.TimeTaskDO;
import com.ibeeking.gmc.global.service.common.enums.TaskJobTypeEnum;
import com.ibeeking.gmc.global.service.common.param.TimeTaskParam;
import com.ibeeking.gmc.global.service.common.query.TimeTaskPageQuery;
import com.ibeeking.gmc.global.service.common.query.TimeTaskQuery;
import com.ibeeking.gmc.global.service.common.vo.TaskJobTypeVO;
import com.ibeeking.gmc.global.service.common.vo.TimeTaskVO;
import com.ibeeking.gmc.global.service.mapper.TimeTaskMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.id.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TimeTaskServiceImpl extends ServiceImpl<TimeTaskMapper, TimeTaskDO> implements ITimeTaskService {

    @Resource
    private TimeTaskMapper timeTaskMapper;

    @Override
    public List<TimeTaskVO> list(TimeTaskQuery query){
        List<TimeTaskVO> timeTaskVOS = new ArrayList<>();
        List<TimeTaskDO> timeTaskDOS = timeTaskMapper.selectList(new LambdaQueryWrapper<TimeTaskDO>()
                .eq(query.getPublishStatus()!= null, TimeTaskDO::getPublishStatus, query.getPublishStatus())
                .eq(query.getId()!= null, TimeTaskDO::getId, query.getId())
                .eq(query.getJobType()!= null, TimeTaskDO::getJobType, query.getJobType())
                .eq(StringUtils.isNotBlank(query.getJobClazz()), TimeTaskDO::getJobClazz, query.getJobClazz())
                .eq(StringUtils.isNotBlank(query.getIndustry()), TimeTaskDO::getIndustry, query.getIndustry())
                .eq(StringUtils.isNotBlank(query.getExecutorHandler()), TimeTaskDO::getExecutorHandler, query.getExecutorHandler())
                .like(StringUtils.isNotBlank(query.getJobName()), TimeTaskDO::getJobName, query.getJobName())
        );
        if(Collections3.isNotEmpty(timeTaskDOS)) {
           timeTaskVOS = timeTaskDOS.stream().map(s->{
               TimeTaskVO entityVO = BeanUtil.convertBean(s, TimeTaskVO.class);
               entityVO.setIndustryName(IndustryTypeEnum.getNameByCode(s.getIndustry()));
               entityVO.setJobTypeName(TaskJobTypeEnum.getDescByType(s.getJobType()));
               return entityVO;
           }).collect(Collectors.toList());
        }
        return timeTaskVOS;
    }

    @Override
    public Page<TimeTaskVO> pageList(TimeTaskPageQuery pageQuery) {
        List<TimeTaskVO> resultVOS = null;
        LambdaQueryWrapper<TimeTaskDO> queryWrapper = new LambdaQueryWrapper<>(TimeTaskDO.class)
                .eq(pageQuery.getPublishStatus()!= null, TimeTaskDO::getPublishStatus, pageQuery.getPublishStatus())
                .eq(pageQuery.getId()!= null, TimeTaskDO::getId, pageQuery.getId())
                .eq(pageQuery.getJobType()!= null, TimeTaskDO::getJobType, pageQuery.getJobType())
                .eq(StringUtils.isNotBlank(pageQuery.getIndustry()), TimeTaskDO::getIndustry, pageQuery.getIndustry())
                .eq(StringUtils.isNotBlank(pageQuery.getJobClazz()), TimeTaskDO::getJobClazz, pageQuery.getJobClazz())
                .eq(StringUtils.isNotBlank(pageQuery.getExecutorHandler()), TimeTaskDO::getExecutorHandler, pageQuery.getExecutorHandler())
                .like(StringUtils.isNotBlank(pageQuery.getJobName()), TimeTaskDO::getJobName, pageQuery.getJobName());
        Page<TimeTaskDO> pagesDOS = timeTaskMapper.selectPage(new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize()), queryWrapper);
        if((pagesDOS !=null) && (pagesDOS.getSize()>0)){
            resultVOS = pagesDOS.getRecords().stream().map(obj -> {
                TimeTaskVO entityVO = BeanUtil.convertBean(obj, TimeTaskVO.class);
                entityVO.setIndustryName(IndustryTypeEnum.getNameByCode(obj.getIndustry()));
                entityVO.setJobTypeName(TaskJobTypeEnum.getDescByType(obj.getJobType()));
                return entityVO;
            }).collect(Collectors.toList());
        }
        Page<TimeTaskVO> pagesVO = new Page<TimeTaskVO>().setRecords(resultVOS).setTotal(pagesDOS.getTotal());
        return pagesVO;
    }

    @Override
    public List<TimeTaskVO> listByIndustry(String industry){
        TimeTaskQuery query = new TimeTaskQuery();
        query.setIndustry(industry);
        query.setPublishStatus(PublishStatusEnum.ENABLE.getValue());
        return getBean().list(query);
    }

    /**
     * 添加定时任务模板
     *
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(TimeTaskParam param) {
        this.checkTimeTask(param);
        TimeTaskDO entityDO = BeanUtil.convertBean(param, TimeTaskDO.class);
        entityDO.setId(IdGenerator.getId());
        return this.timeTaskMapper.insert(entityDO) > 0;
    }


    /**
     * 修改定时任务模板
     *
     * @param param
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean modify(TimeTaskParam param) {
        this.checkTimeTask(param);
        TimeTaskDO entityDO = BeanUtil.convertBean(param, TimeTaskDO.class);
        return this.timeTaskMapper.updateById(entityDO) > 0;
    }


    /**
     * 根据id删除定时任务模板
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean del(Long id) {
        return this.timeTaskMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean changeStatus(Long tenantId, Integer status) {
        TimeTaskDO entityDO = this.timeTaskMapper.selectById(tenantId);
        if(entityDO == null) return false;
        entityDO.setId(tenantId);
        entityDO.setPublishStatus(status);
        return this.timeTaskMapper.updateById(entityDO) > 0;
    }

    /**
     * 根据id查看详情
     *
     * @param id
     * @return
     */
    @Override
    public TimeTaskVO view(Long id) {
        TimeTaskDO entityDO = this.timeTaskMapper.selectById(id);
        TimeTaskVO entityVO = BeanUtil.convertBean(entityDO, TimeTaskVO.class);
        entityVO.setIndustryName(IndustryTypeEnum.getNameByCode(entityDO.getIndustry()));
        entityVO.setJobTypeName(TaskJobTypeEnum.getDescByType(entityDO.getJobType()));
        return entityVO;
    }

    /**
     * 根据id查看详情
     *
     * @param id
     * @return
     */
    @Override
    public TimeTaskDTO queryTimeTaskById(Long id) {
        TimeTaskDO entityDO = this.timeTaskMapper.selectById(id);
        TimeTaskDTO entityDTO = BeanUtil.convertBean(entityDO, TimeTaskDTO.class);
        return entityDTO;
    }

    /**
     * 查看详情
     *
     * @param handler
     * @return
     */
    @Override
    public TimeTaskDTO queryTimeTaskByIndustryAndHandler(String industry, String handler){
        LambdaQueryWrapper<TimeTaskDO> queryWrapper = new LambdaQueryWrapper<>(TimeTaskDO.class)
                .eq(TimeTaskDO::getIndustry,industry)
                .eq(TimeTaskDO::getExecutorHandler,handler)
                .eq(TimeTaskDO::getPublishStatus,PublishStatusEnum.ENABLE.getValue());
        TimeTaskDO entityDO = this.timeTaskMapper.selectOne(queryWrapper);
        TimeTaskDTO entityDTO = BeanUtil.convertBean(entityDO, TimeTaskDTO.class);
        return entityDTO;
    }

    @Override
    public List<TaskJobTypeVO> taskJobType() {
        List<TaskJobTypeVO> result = new ArrayList<>();
        TaskJobTypeVO entityVO = null;
        for (TaskJobTypeEnum jobTypeEnum : TaskJobTypeEnum.values()) {
            entityVO = new TaskJobTypeVO();
            entityVO.setType(jobTypeEnum.getType());
            entityVO.setDesc(jobTypeEnum.getDesc());
            result.add(entityVO);
        }
        return result;
    }

    /**
     * 检查是否有重复
     *
     * @param param
     */
    private void checkTimeTask(TimeTaskParam param) {
        QueryWrapper<TimeTaskDO> quary = new QueryWrapper<>();
        quary.lambda().eq(TimeTaskDO::getIndustry, param.getIndustry())
                .ne(param.getId() != null, TimeTaskDO::getId, param.getId())
                .eq(StringUtils.isNotEmpty(param.getJobName()), TimeTaskDO::getJobName, param.getJobName());
        List<TimeTaskDO> TimeTaskList = this.timeTaskMapper.selectList(quary);
        if (Collections3.isNotEmpty(TimeTaskList)) {
            throw new BusinessException("名称不能重复");
        }
    }
    private static ITimeTaskService getBean() {
        return SpringBeanUtil.getBean(ITimeTaskService.class);
    }
}
